package dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Session;
import org.hibernate.Transaction;

import util.Constantes;
import util.HibernateUtil;
import vo.BSCPerspectiveVO;
import vo.BscGoalVO;
import vo.BscVO;
import vo.MetricVO;
import vo.SwotElementVO;
import entity.BSC;
import entity.BSCElement;
import entity.BSCGoal;
import entity.BSCMetric;
import entity.BSC_Perspective;
import entity.Opportunity;
import entity.SWOTElement;
import entity.StrategicPlan;
import entity.Strength;
import entity.Threat;
import entity.Weakness;

public class BscDAO {
	
	public BscVO getBsc(int strategicPlanId) {
		Session sessao = HibernateUtil.getSession();
		
		Map<String, BSCPerspectiveVO> mapaBscPerspective = new HashMap<String, BSCPerspectiveVO>();
		BscVO bscVO = new BscVO();
		
		StrategicPlan sp = (StrategicPlan) sessao.load(StrategicPlan.class, strategicPlanId);
		
		for(Object obj:sp.getListPerspectives()){
			BSC_Perspective bspp = (BSC_Perspective) obj;
			
			BSCPerspectiveVO bsppVO = new BSCPerspectiveVO();
			bsppVO.setPerspective(bspp.getStrategicPerspective().getName());
			bsppVO.setListaBscGoal(new ArrayList<BscGoalVO>());
			bsppVO.setId(bspp.getId());
			bsppVO.setAcronym(bspp.getStrategicPerspective().getAcronym());
			
			mapaBscPerspective.put(bspp.getStrategicPerspective().getAcronym(), bsppVO);
		}
		
		bscVO.setStrategicPlanId(strategicPlanId);
		bscVO.setOrganizationName(sp.getOrganizacao().getName());
		bscVO.setStrategicPlanName(sp.getNome());
		
		if (sp.getBsc() != null){
			BSC bsc = sp.getBsc();
			
			bscVO.setId(bsc.getId());			
			
			for(BSCElement bsce:bsc.getListBSCElement()){
				if (bsce instanceof BSCGoal){
					BSCGoal bscGoal = (BSCGoal) bsce;
					BscGoalVO vo = new BscGoalVO();
					vo.setName(bscGoal.getName());
					vo.setPerspectiva(bscGoal.getPerspective().getStrategicPerspective().getName());
					vo.setPerspectivaId(bscGoal.getPerspective().getId());
					vo.setId(bscGoal.getId());
					
					List<SwotElementVO> listDerivedSwotElement = new ArrayList<SwotElementVO>();
					for(SWOTElement se:bscGoal.getListRelatedSwotElement()){
						SwotElementVO sevo = new SwotElementVO();
						sevo.setId(se.getId());
						sevo.setName(se.getName());
						
						if (se instanceof Strength){
							sevo.setElementType(Constantes.STRENGTH);
						}
						else if (se instanceof Weakness){
							sevo.setElementType(Constantes.WEAKNESS);
						}
						else if (se instanceof Opportunity){
							sevo.setElementType(Constantes.OPPORTUNITY);
						}
						else if (se instanceof Threat){
							sevo.setElementType(Constantes.THREAT);
						}
						
						listDerivedSwotElement.add(sevo);
					}
					
					vo.setListDerivedSwotElement(listDerivedSwotElement);
					
					List<MetricVO> metrics = new ArrayList<MetricVO>();
					for(BSCMetric m:bscGoal.getMetrics()){
						MetricVO mvo = new MetricVO();
						mvo.setDescription(m.getDescription());
						mvo.setName(m.getName());
						mvo.setId(m.getId());
						metrics.add(mvo);
					}
					
					vo.setMetrics(metrics);
					
					mapaBscPerspective.get(bscGoal.getPerspective().getStrategicPerspective().getAcronym()).getListaBscGoal().add(vo);
				}
			}
		}
		else{
			bscVO.setId(-1);
		}
		
		bscVO.setMapaBscPerspective(mapaBscPerspective);
		
		sessao.close();
		return bscVO;
	}

	public void save(BscVO bscVO) {
		BSC bsc;
		
		Session sessao = HibernateUtil.getSession();
		
		if (bscVO.getId() > 0){
			bsc = (BSC) sessao.load(BSC.class, bscVO.getId());
		}
		else{
			bsc = new BSC();
			StrategicPlan sp = (StrategicPlan) sessao.load(StrategicPlan.class, bscVO.getStrategicPlanId());
			bsc.setStrategicPlan(sp);
			bsc.setListBSCElement(new ArrayList<BSCElement>());
		}
		
		for(String key:bscVO.getMapaBscPerspective().keySet()){
			BSCPerspectiveVO vo = bscVO.getMapaBscPerspective().get(key);
			BSC_Perspective bscp = (BSC_Perspective) sessao.load(BSC_Perspective.class, vo.getId());
						
			for(BscGoalVO goal:vo.getListaBscGoal()){
				BSCGoal bscGoal;
				
				if(goal.getId() == 0){
					bscGoal = new BSCGoal();
				}
				else{
					bscGoal = (BSCGoal) sessao.load(BSCGoal.class, goal.getId());
					
					if (goal.getStatus() == Constantes.UPDATE)
						bsc.getListBSCElement().remove(bscGoal);
				}

				bscGoal.setListRelatedSwotElement(new ArrayList<SWOTElement>());
				bscGoal.setMetrics(new ArrayList<BSCMetric>());
				
				for(SwotElementVO sevo:goal.getListDerivedSwotElement()){					
					SWOTElement se = (SWOTElement) sessao.load(SWOTElement.class, sevo.getId());
					bscGoal.getListRelatedSwotElement().add(se);
				}
				
				for(MetricVO mvo:goal.getMetrics()){
					BSCMetric metric = (BSCMetric) sessao.load(BSCMetric.class, mvo.getId());
					bscGoal.getMetrics().add(metric);
				}
				
				bscGoal.setBsc(bsc);
				bscGoal.setName(goal.getName());
				bscGoal.setPerspective(bscp);
				
				bsc.getListBSCElement().add(bscGoal);
			}
		}
		
		Transaction tx = sessao.beginTransaction();
		
		try{
			sessao.saveOrUpdate(bsc);
			tx.commit();
			sessao.close();
		}
		catch(Exception e){			
			e.printStackTrace();
			tx.rollback();	
			sessao.close();
		}
	}
}
